﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Billing.Dtos;
using Billing.Utilities;

namespace Billing.Controls
{
    /// <summary>
    /// Interaction logic for BillginGridControl.xaml
    /// </summary>
    public partial class BillingGridControl : UserControl
    {
        double screenHeight = 0;

        public BillingGridControl()
        {
            InitializeComponent();
            ReadItems();
            ltMainList.Items.Add(new BillingGridItemControl(CacheManager.BillingItems, this));
            ltMainList.Focus();
            ltMainList.SelectedIndex = 0;
            UpdateBillItemsSlNo();
            screenHeight = this.Height;
            ltMainList.Height = screenHeight / 1.7;
            BillingGridItemControl firstItem = (BillingGridItemControl)ltMainList.SelectedItem;
            firstItem.txtCode.Focus();
        }

        private void ltMainList_KeyDown(object sender, KeyEventArgs e)
        {
            BillingGridItemControl item = GetCurrentGridItem();
            if (e.Key == Key.Enter)
            {
                if (item != null && item.txtCode.IsFocused)
                {
                    if (item.txtCode.Text.Trim() != string.Empty && IsCodeExist(Convert.ToInt32(item.txtCode.Text.Trim())))
                    {
                        item.txtQty.Focus();
                        item.txtQty.SelectAll();
                    }
                }
                else if (item == null || item.txtQty.IsFocused)
                {
                    if (GetBillingGridLastItem().txtCode.Text.ToString().Trim() != string.Empty && GetBillingGridLastItem().txtQty.Text.ToString().Trim() != string.Empty)
                    {
                        ltMainList.Items.Add(new BillingGridItemControl(CacheManager.BillingItems, this));
                        ltMainList.SelectedIndex = ltMainList.SelectedIndex + 1;
                    }
                    GetBillingGridLastItem().txtCode.Focus();
                    FocusOnLastItem();
                    UpdateBillItemsSlNo();
                }
                if (ltMainList.Items.Count <= 0)
                {
                    ltMainList.Items.Add(new BillingGridItemControl(CacheManager.BillingItems, this));
                    FocusOnLastItem();
                }
            }
            else if (e.Key == Key.Escape)
            {
                MessageBox.Show("Do you want to discard this bill?", "Warning", MessageBoxButton.YesNo, MessageBoxImage.Warning);                    
            }

            RefreshAllFields();
        }

        private void ltMainList_PreviewKeyUp(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Up)
            {
                ltMainList.SelectedIndex = ltMainList.SelectedIndex > 0 ? ltMainList.SelectedIndex - 1 : 0;
                BillingGridItemControl item = (BillingGridItemControl)ltMainList.SelectedItem;
                item.txtCode.Focus();
            }
            else if (e.Key == Key.Down)
            {
                ltMainList.SelectedIndex = ltMainList.SelectedIndex + 1;
                BillingGridItemControl item = (BillingGridItemControl)ltMainList.SelectedItem;
                item.txtCode.Focus();
            }
            else if (e.Key == Key.Delete)
            {
                if (ltMainList.Items.Count != 0)
                {
                    int selectedIndex = ltMainList.SelectedIndex;
                    ltMainList.Items.RemoveAt(ltMainList.SelectedIndex);
                    ltMainList.SelectedIndex = selectedIndex;
                    if (ltMainList.SelectedItem == null)
                    {
                        FocusOnLastItem();
                        GetBillingGridLastItem().txtCode.Focus();
                    }
                    else
                    {
                        BillingGridItemControl item = GetCurrentGridItem();
                        item.txtCode.Focus();
                    }
                    UpdateBillItemsSlNo();
                    UpdateTotalCost();
                    UpdateTotalQty();
                }
            }
        }

        #region Private Methods

        private bool IsCodeExist(int p)
        {
            BillingGridItemDto billItem = CacheManager.BillingItems.Find(item => item.Code == p);
            return billItem != null;
        }

        void UpdateBillItemsSlNo()
        {
            int SlNo = 1;
            foreach (BillingGridItemControl itemControl in ltMainList.Items)
            {
                itemControl.lblSrNo.Content = SlNo++;
            }
        }

        BillingGridItemControl GetBillingGridLastItem()
        {
            return (BillingGridItemControl)GetLastItemObjet();
        }

        BillingGridItemControl GetCurrentGridItem()
        {
            return (BillingGridItemControl)ltMainList.SelectedItem;
        }

        object GetLastItemObjet()
        {
            if (ltMainList.Items.Count > 0)
                return ltMainList.Items[ltMainList.Items.Count - 1];
            else
                return new BillingGridItemControl(CacheManager.BillingItems);
        }

        void FocusOnLastItem()
        {
            ltMainList.SelectedIndex = ltMainList.Items.Count - 1;
        }

        void ReadItems()
        {
            CacheManager.LoadItems();
        }

        #endregion

        #region Public Methods

        public void UpdateTotalQty()
        {
            double totalItems = 0;

            foreach (BillingGridItemControl item in ltMainList.Items)
            {
                if (item.txtQty.Text != string.Empty)
                    totalItems += Convert.ToInt64(item.txtQty.Text.Trim());
            }

            txtQty.Text = totalItems.ToString();
        }

        public void UpdateTotalCost()
        {
            long totalCost = 0;

            foreach (BillingGridItemControl item in ltMainList.Items)
            {
                if (item.txtPrice.Text != string.Empty)
                    totalCost += Convert.ToInt64(item.txtPrice.Text.Trim());
            }

            txtNetTotal.Text = txtTotal.Text = totalCost.ToString();
        }

        public void RefreshAllFields()
        {
            UpdateTotalCost();
            UpdateTotalQty();
            UpdateBillItemsSlNo();
        }

        #endregion
    }
}
